package com.lcc.lynx.jdbc.qw;

import com.lcc.lynx.common.exception.e.JDBCException;
import com.lcc.lynx.common.utils.StrUtil;
import com.lcc.lynx.jdbc.enums.Operator;
import com.lcc.lynx.jdbc.enums.QwOperator;
import lombok.Data;

/**
 * @author lcc
 * @date 2025/7/23 14:11
 */
@Data
public class QueryCondition extends QwCondition {

    private Column column;
    private Operator operator;
    private QwOperator qwOperator;
    private QueryWrapper queryWrapper;
    private QueryCondition queryCondition;
    private ColumnCondition columnCondition;


    public QueryCondition() {
    }

    public QueryCondition(String columnName, Operator operator, TableDef tableDef, Object... values) {

        this.columnName = columnName;
        this.operator = operator;
        Object value = values.length > 0 ? values[0] : null;
        if (value instanceof Column) {
            this.column = (Column) value;
        } else if (value instanceof QueryCondition) {
            this.queryCondition = (QueryCondition) value;
        } else {
            this.values = values;
        }
        this.tableDef = tableDef;
    }

    public QueryCondition(Operator operator, QueryWrapper queryWrapper) {
        this.operator = operator;
        this.queryWrapper = queryWrapper;
    }

    public String build(QueryWrapper qw) {
        if (columnCondition != null && columnName == null) {
            columnName = columnCondition.build(qw);
        }
        String str;
        if1:
        if (column != null) {
            str = tableColumnName(qw) + " = " + column.tableColumnName(qw);
        } else if (operator.hasArg()) {
            if (operator == Operator.IN || operator == Operator.NOT_IN) {
                if (queryCondition != null) {
                    str = tableColumnName(qw) + " " + operator.value().replace("?", queryCondition.build(qw));
                    break if1;
                }
                StringBuilder s = new StringBuilder();
                for (int i = 0; i < values.length; i++) {
                    s.append(i != 0 ? ", " : "");
                    if (values[i] instanceof Number) {
                        s.append(values[i]);
                    } else {
                        int size = qw.getParams().size();
                        qw.getParams().put("p" + size, values[i]);
                        s.append("#{params.p").append(size).append("}");
                    }
                }
                str = tableColumnName(qw) + " " + operator.value().replace("?", s.toString());
            } else if (operator == Operator.NOT_EQUAL && values.length == 1 && values[0] instanceof String) {
                int size = qw.getParams().size();
                qw.getParams().put("p" + size, values[0]);
                str = "coalesce(" + tableColumnName(qw) + ", '') != #{params.p" + size + "}";
            } else if (operator == Operator.EXISTS || operator == Operator.NOT_EXISTS || operator == Operator.RECURSIVE) {
                if (queryWrapper == null) {
                    throw new JDBCException(operator.name() + " 时queryWrapper参数不能为空");
                }
                str = operator.value().replace("?0", queryWrapper.buildSql(qw));
            } else {
                String s = operator.value();
                for (int i = 0; i < values.length; i++) {
                    Object value = values[i];
                    if (value instanceof Number) {
                        s = s.replace("#{?" + i + "}", value.toString());
                    } else {
                        int size = qw.getParams().size();
                        qw.getParams().put("p" + size, values[i]);
                        s = s.replace("?" + i, "params.p" + size);
                    }
                }
                str = tableColumnName(qw) + " " + s;
            }
        } else {
            str = tableColumnName(qw) + " " + operator.value();
        }
        if (queryCondition != null && (qwOperator == QwOperator.OR || qwOperator == QwOperator.AND)) {
            str = String.format(qwOperator.value(), str, queryCondition.build(qw));
        }
        return str;
    }

    public boolean isNotEmpty() {
        return StrUtil.isNotEmpty(values) && StrUtil.isNotEmpty(values[0])
                || column != null
                || operator != null && !operator.hasArg()
                || queryWrapper != null;
    }

    public QueryCondition or(QueryCondition queryCondition) {
        this.queryCondition = queryCondition;
        this.qwOperator = QwOperator.OR;
        return this;
    }

    public QueryCondition and(QueryCondition queryCondition) {
        this.queryCondition = queryCondition;
        this.qwOperator = QwOperator.AND;
        return this;
    }

}
